/*
 * ParserPev.java   (7.aug.07)
 *
 * @author      Lobsang Alvites Szaler
 * @version     0.10
 *
 * Copyright (c) Soluciones Info MĂłviles SAC
 *
 */

package sim.utils;

import sim.utils.*;
import sim.utils.parser.*;
import sim.framework.*;
import sim.framework.io.*;

///#define DEBUG_PARSERPEV

public abstract class ParserPev implements ParserScan, FileGets {
    
    private final byte PEV_ERROR_OPENFILE  = -2;
    private final byte PEV_ERROR_SYNTAXIS  = -1;
    private final byte PEV_ERROR_NONE      = 0;
    
    // Variables to get field values
    private int     m_Param_ofst;
    private int     m_Param_len;
    private int     m_Value_ofst;
    private int     m_Value_len;
    
    private Parser  m_Parser;
    
    /*
     *  Constructicon
     */
    public ParserPev() {
	m_Parser = new Parser(this, Utils.TOKEN, Utils.TOKEN_EQUALS, 1, Parser.FORWARD);
    }
    
    /*
     * Esta funcion abre el file 'fname', verifica que no hayan errores y
     * empieza a leer cada linea desde el file, verificando la validez del
     * formato y luego llamando a la funcion setEntry() encargada de procesar
     * los campos extraidos.
     * Si no hubo error (err = PEV_ERROR_NONE), la funciĂłn setentry()
     * recibe como parametros las cadenas de caracteres param y value.
     * Caso contrario param y value valen NULL y err contiene el error:
     * PEV_ERROR_OPENFILE
     * PEV_ERROR_SYNTAXIS
     *
     * Las lineas que empiezan con el caracter '#' o ';' son ignoradas.
     * Despues de un caracter '#' se ignora el contenido.
     */
    public void readCfg( final Simlet s, final String fname ) {
        FileStream  file = null;
        byte        err = PEV_ERROR_NONE;
        byte[]      abyte = null;
        
        // Try to open the file, or returns an error.
        if( fname == null ) {
            err = PEV_ERROR_OPENFILE;
        } else {
            file = (FileStream)FileStream.create( s, fname, File.MODE_READ);
            if( file == null ) {
                err = PEV_ERROR_OPENFILE;
            } else {
                // Succeeded! Initialize the Parser and begin to parse
                
//                // PRUEBAS DESDE MEMORIA
//                for( int i=0; i<mem_appcfg.length; i++ ) {
//                    fileGetsLine( mem_appcfg[i].getBytes(), mem_appcfg[i].length(), 0 );
//                }
                
                file.gets( (FileGets)this );
                file.close();
            }
        }
        
        if( err == PEV_ERROR_OPENFILE ) {
            m_Param_len = 0;
            m_Value_len = 0;
            parserEnd(true);
        }
    }
    
    public byte[]   m_aByte;
    
    /*
     *  A "callback" from FileGets class
     */
    public boolean fileGetsLine( final byte[] abyte, int len, final int lenEOL ) {
        int p;
	if (len > lenEOL) {
	    // If a line is Disabled, then skip parsing it
	    if( Utils.memmem( abyte, 0, 1, Utils.TOKEN, Utils.TOKEN_SEMICOLON, 1 ) == -1 ) {
		// Strips End Of Line characters
		len -= lenEOL;
		// Strips text after a Comment
		p = Utils.memmem( abyte, 0, len, Utils.TOKEN, Utils.TOKEN_POUND, 1 );
		if( p > -1 ) {
		    len = p;
		}
		// Checks the validity of PEV line format (in other words, at least
		// a char '=' starting at offset 1)
		if( Utils.memmem( abyte, 0, len, Utils.TOKEN, Utils.TOKEN_EQUALS, 1 ) > 0 ) {
		    m_aByte = abyte;
		    m_Parser.scan( abyte, 0, len );
		} else {
		    m_Param_len = 0;
		    m_Value_len = 0;
		    parserEnd(true);
		}
	    }
	}
        return true;
    }
    
    
    public final boolean parserHit( final int hit, final byte[] line, int ofst, int len, Object something) {
        boolean bEnd = false;
        switch( hit )  {
            case 1:
                m_Param_ofst = ofst;
                m_Param_len = len;
                bEnd = true;
                break;
            case 2:
                m_Value_ofst = ofst;
                m_Value_len = len;
                bEnd = true;
                break;
        }
        return bEnd;
    }
    
    public final boolean parserEnd(boolean cancel) {
        int     err = PEV_ERROR_NONE;
        String  strParam = null;
        String  strValue = null;
        
        if( m_Param_len == 0 || m_Value_len == 0 ) {
            err = PEV_ERROR_SYNTAXIS;
//#if DEBUG_PARSERPEV
//#         System.out.println("ParserPEV PEV_ERROR_SINTAXIS" );
//#endif
        } else {
            strParam = new String(m_aByte,m_Param_ofst,m_Param_len);
            strValue = new String(m_aByte,m_Value_ofst,m_Value_len);
            // Removes spaces
            strParam.trim();
            strValue.trim();
            
//#if DEBUG_PARSERPEV
//#         System.out.println("ParserPEV param: "+ strParam );
//#         System.out.println("ParserPEV value: "+ strValue );
//#endif
        }
        
        setEntry( strParam, strValue, err );

	return true;
    }
    
    protected abstract void setEntry( String strp , String strv, int err );
    
    
    //-----------------------------------------
    // PRUEBAS DESDE MEMORIA
    //-----------------------------------------
    
//    private final String mem_appcfg[] = {
//        "batch=1",
//        "clrback=FFFFFF",
//        "clrline=0000FF",
//        "clrselback=0000FF",
//        "clrseltext=FFFFFF",
//        "clrtext=000000",
//        "sendini=1",
//        "single=04",
//        "syncdlg=0",
//        "syncper=0",
//        "timeout=0",
//    };
    
}
